package com.annotation.mvc.util;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.annotatin.mvc.interfaceAnnotation.*;

public class CurrentListener implements ServletContextListener{
	private ServletContext context;
	public void contextInitialized(ServletContextEvent event) {
		System.out.println(getClass()+" listener init started");
		context= event.getServletContext();
		String path = context.getRealPath("")+context.getInitParameter("setup");
		SAXReader reader = new SAXReader();
		Map<String, String> map = new HashMap<String, String>();
		try {
			Document doc = reader.read(new File(path));
			Element root = doc.getRootElement();
			Element e = root.element("search");
			String[] packages = e.attributeValue("package").split(",");
			List<Class> list = new ArrayList<Class>();
			String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
			for(String pack : packages){
				File file = new File(classpath+pack.replace(".","/"));
				File[] files = file.listFiles();
				for(File f : files){
					if(!f.isDirectory()){
						try {
							String fname = f.getName().substring(0, f.getName().lastIndexOf("."));
							list.add(Class.forName(pack+"."+fname));
						} catch (ClassNotFoundException ex) {
							ex.printStackTrace();
						}
					}
				}
			}
			for(Class clazz : list){
				Control cont = (Control) clazz.getAnnotation(Control.class);
				if(cont!=null){
					RequestMapping req_class = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
					Method[] methods = clazz.getMethods();
					for(Method method : methods){
						RequestMapping req = method.getAnnotation(RequestMapping.class);						
						if(req!=null){
							StringBuffer paraNames = new StringBuffer();
							for(Class para : method.getParameterTypes()){
								paraNames.append(","+para.getName());
							}
							String url = req.value();
							map.put(req_class.value()+url+".do", clazz.getName()+"||"+method.getName()+"||"+paraNames.substring(1));
						}
					}
				}
			}
//			Element e = root.element("control");
//			String classurl = e.attributeValue("url");
//			String classpath = e.attributeValue("class");
//			Iterator itr= e.elementIterator();
//			while(itr.hasNext()){
//				Element methodElet = (Element) itr.next();
//				String methodUrl = methodElet.attributeValue("url");
//				String methodMame = methodElet.attributeValue("name");
//				String parameterName = methodElet.attributeValue("paras");
//				map.put(classurl+methodUrl+".do", classpath+"||"+methodMame+"||"+parameterName);
//			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
		context.setAttribute("setup", map);
		System.out.println(getClass()+" listener init finished.");
	}
	

	public void contextDestroyed(ServletContextEvent e) {
		System.out.println(getClass()+" listener destroy finished.");
	}
}

